//
// Created by 11510 on 2024/6/25.
//
#include <iostream>
#include <list>
#include <set>
#include <vector>
#include <valarray>
using namespace std;


class Point {
public:
    Point(int x = 0, int y = 0) : _ix(x), _iy(y) {
        printf("Point()\n");
    }

    Point(const Point &point) : _ix(point._ix), _iy(point._iy) {
        printf("copy Point()\n");
    }

    double getDistance() const {
        return hypot(_ix, _iy);
    }
    int getX() const{
        return _ix;
    }
    int getY() const{
        return _iy;
    }

    friend ostream &operator<<(ostream &os, const Point &rhs);

    friend bool operator<(const Point &lhs, const Point &rhs);

private:
    int _ix;
    int _iy;
};

/**
 * WARNING：调用要放在特化之后！
 */
namespace std {
    template<>
    struct less<Point> {
        /* 屎 */
        bool operator()(const Point &lhs, const Point &rhs) {
            if (lhs.getDistance() < rhs.getDistance()) {
                return true;
            } else if (lhs.getDistance() == rhs.getDistance()) {
                if (lhs.getX() < rhs.getX()) {
                    return true;
                } else if (lhs.getX() == rhs.getX()) {
                    if (lhs.getY() < rhs.getY()) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    };
}//end of namespace std


std::ostream &operator<<(std::ostream &ostr, const std::set<Point> &rhs) {
    for (auto &i: rhs) {
        ostr << " " << i;
    }
    return ostr;
}

ostream &operator<<(ostream &os, const Point &rhs) {
    return os << "(" << rhs._ix << "," << rhs._iy << ")";
}

bool operator<(const Point &lhs, const Point &rhs) {
    double m1 = sqrt(pow(lhs._ix, 2) + pow(lhs._iy, 2));
    double m2 = sqrt(pow(rhs._ix, 2) + pow(rhs._iy, 2));
    return m1 < m2;
}





void test1() {
    set<Point> setPoint = {
            Point(1, 2),
            Point(-1, 3),
            Point(0, 0)
    };

    cout << setPoint;
}

int main() {
    test1();
    return 0;
}